
// FICD
#pragma config ICS = PGD1    // ICD Communication Channel Select bits->Communicate on PGEC1 and PGED1
#pragma config JTAGEN = OFF    // JTAG Enable bit->JTAG is disabled

// FPOR
#pragma config ALTI2C1 = OFF    // Alternate I2C1 pins->I2C1 mapped to SDA1/SCL1 pins
#pragma config ALTI2C2 = OFF    // Alternate I2C2 pins->I2C2 mapped to SDA2/SCL2 pins
#pragma config WDTWIN = WIN75    // Watchdog Window Select bits->WDT Window is 75% of WDT period

// FWDT
#pragma config WDTPOST = PS8    // Watchdog Timer Postscaler bits->1:32768
#pragma config WDTPRE = PR128    // Watchdog Timer Prescaler bit->1:128
#pragma config PLLKEN = ON    // PLL Lock Enable bit->Clock switch to PLL source will wait until the PLL lock signal is valid.
#pragma config WINDIS = OFF    // Watchdog Timer Window Enable bit->Watchdog Timer in Non-Window mode
#pragma config FWDTEN = OFF    // Watchdog Timer Enable bit->Watchdog timer enabled/disabled by user software

// FOSC
#pragma config POSCMD = XT    // Primary Oscillator Mode Select bits->XT Crystal Oscillator Mode
#pragma config OSCIOFNC = ON    // OSC2 Pin Function bit->OSC2 is general purpose digital I/O pin
#pragma config IOL1WAY = ON    // Peripheral pin select configuration->Allow only one reconfiguration
#pragma config FCKSM = CSECMD    // Clock Switching Mode bits->Clock switching is enabled,Fail-safe Clock Monitor is disabled

// FOSCSEL
#pragma config FNOSC = PRIPLL    // Oscillator Source Selection->PRIPLL
#pragma config IESO = ON    // Two-speed Oscillator Start-up Enable bit->Start up device with FRC, then switch to user-selected oscillator source

// FGS
#pragma config GWRP = OFF    // General Segment Write-Protect bit->General Segment may be written
#pragma config GCP = OFF    // General Segment Code-Protect bit->General Segment Code protect is Disabled


#include "system.h"

/****************************************************************************
     * Set the PPS
     * 
     * 
     * input RPINRx,example RPINR18bits.U1RXR = 0x0026; 
     * 将输入功能分配給RPn
     * 
     *  输入名称(1)    功能名称    寄存器    配置位
        外部中断1       INT1      RPINR0   INT1R<6:0>
        外部中断2       INT2      RPINR1   INT2R<6:0>
        外部中断3       INT3      RPINR1   INT3R<6:0>
        外部中断4       INT4      RPINR2   INT4R<6:0>
        Timer2      外部时钟T2CK  RPINR3   T2CKR<6:0>
        Timer3      外部时钟T3CK  RPINR3   T3CKR<6:0>
        Timer4      外部时钟T4CK  RPINR4   T4CKR<6:0>
        Timer5      外部时钟T5CK  RPINR4   T5CKR<6:0>
        Timer6      外部时钟T6CK  RPINR5   T6CKR<6:0>
        Timer7      外部时钟T7CK  RPINR5   T7CKR<6:0>
        Timer8      外部时钟T8CK  RPINR6   T8CKR<6:0>
        Timer9      外部时钟T9CK  RPINR6   T9CKR<6:0>
        输入捕捉1        IC1      RPINR7   IC1R<6:0>
        输入捕捉2        IC2      RPINR7   IC2R<6:0>
        输入捕捉3        IC3      RPINR8   IC3R<6:0>
        输入捕捉4        IC4      RPINR8   IC4R<6:0>
        输入捕捉5        IC5      RPINR9   IC5R<6:0>
        输入捕捉6        IC6      RPINR9   IC6R<6:0>
        输入捕捉7        IC7      RPINR10  IC7R<6:0>
        输入捕捉8        IC8      RPINR10  IC8R<6:0>
        输出比较故障A    OCFA     RPINR11  OCFAR<6:0>
        输出比较故障B    OCFB     RPINR11  OCFBR<6:0>
        PMW故障1        FLT1     RPINR12  FLT1R<6:0>
        PMW故障2        FLT2     RPINR12  FLT2R<6:0>
        PMW故障3        FLT3     RPINR13  FLT3R<6:0>
        PMW故障4        FLT4     RPINR13  FLT4R<6:0>
        QEI1A相         QEA1     RPINR14  QEA1R<6:0>
        QEI1B相         QEB1     RPINR14  QEB1R<6:0>
        QEI1索引        INDX1    RPINR15  INDX1R<6:0>
        QEI1起始位置    HOME1    RPINR15   HOM1R<6:0>
        QEI2A相         QEA2     RPINR16  QEA2R<6:0>
        QEI2B相         QEB2     RPINR16  QEB2R<6:0>
        QEI2索引       INDX2     RPINR17  INDX2R<6:0>
        QEI2起始位置   HOME2     RPINR17  HOM2R<6:0>
        UART1接收      U1RX      RPINR18  U1RXR<6:0>
        UART1允许发送  U1CTS     RPINR18  U1CTSR<6:0>
        UART2接收      U2RX      RPINR19  U2RXR<6:0>
        UART2允许发送  U2CTS     RPINR19  U2CTSR<6:0>
        SPI1数据输入   SDI1      RPINR20  SDI1R<6:0>
        SPI1时钟输入   SCK1IN    RPINR20  SCK1R<6:0>
        SPI1从选择    SS1IN      RPINR21  SS1R<6:0>
        SPI2数据输入   SDI2      RPINR22  SDI2R<6:0>
        SPI2时钟输入  SCK2IN     RPINR22  SCK2R<6:0>
        SPI2从选择    SS2IN      RPINR23  SS2R<6:0>
        DCI数据输入    CSDI      RPINR24  CSDIR<6:0>
        DCI时钟输入   CSCKIN     RPINR24  CSCKR<6:0>
      DCI FSYNC输入   COFSIN     RPINR25  COFSR<6:0>
        CAN1接收      C1RX       RPINR26  C1RXR<6:0>
        CAN2接收      C2RX       RPINR26  C2RXR<6:0>
        UART3接收     U3RX       RPINR27  U3RXR<6:0>
        UART3允许发送 U3CTS      RPINR27  U3CTSR<6:0>
        UART4接收     U4RX       RPINR28  U4RXR<6:0>
        UART4允许发送 U4CTS      RPINR28  U4CTSR<6:0>
        SPI3数据输入  SDI3       RPINR29  SDI3R<6:0>
        SPI3时钟输入  SCK3IN     RPINR29  SCK3R<6:0>
        SPI3从选择    SS3IN      RPINR30  SS3R<6:0>
        SPI4数据输入  SDI4       RPINR31  SDI4R<6:0>
        SPI4时钟输入  SCK4IN     RPINR31  SCK4R<6:0>
        SPI4从选择    SS4IN      RPINR32  SS4R<6:0>
        输入捕捉9     IC9        RPINR33  IC9R<6:0>
        输入捕捉10    IC10       RPINR33  IC10R<6:0>
        输入捕捉11    IC11       RPINR34  IC11R<6:0>
        输入捕捉12    IC12       RPINR34  IC12R<6:0>
        输入捕捉13    IC13       RPINR35  IC13R<6:0>
        输入捕捉14    IC14       RPINR35  IC14R<6:0>
        输入捕捉15    IC15       RPINR36  IC15R<6:0>
        输入捕捉16    IC16       RPINR36  IC16R<6:0>
        输出比较故障C OCFC       RPINR37  OCFCR<6:0>
     * 
     * 
     * output RPORx, example RPOR1bits.RP37R = 0x0001;
     * 将RPn分配給输出功能
     * 
     *  功能        RPnR<5:0>  输出名称
        默认端口    000000      RPn连接到默认引脚
        U1TX        000001     RPn连接到UART1 发送
        U1RTS       000010     RPn连接到UART1 请求发送
        U2TX        000011     RPn连接到UART2 发送
        U2RTS       000100     RPn连接到UART2 请求发送
        SDO1        000101     RPn连接到SPI1 数据输出
        SCK1OUT     000110     RPn连接到SPI1 时钟输出
        SS1OUT      000111     RPn连接到SPI1 从选择
        SDO2        001000     RPn连接到SPI2 数据输出
        SCK2OUT     001001     RPn连接到SPI2 时钟输出
        SS2OUT      001010     RPn连接到SPI2 从选择
        CSDO        001011     RPn连接到DCI 数据输出
        CSCKOUT     001100     RPn连接到DCI 时钟输出
        COFSOUT     001101     RPn连接到DCI FSYNC 输出
        C1TX        001110     RPn连接到CAN1 发送
        C2TX        001111     RPn连接到CAN2 发送
        OC1         010000     RPn连接到输出比较1 输出
        OC2         010001     RPn连接到输出比较2 输出
        OC3         010010     RPn连接到输出比较3 输出
        OC4         010011     RPn连接到输出比较4 输出
        OC5         010100     RPn连接到输出比较5 输出
        OC6         010101     RPn连接到输出比较6 输出
        OC7         010110     RPn连接到输出比较7 输出
        OC8         010111     RPn连接到输出比较8 输出
        C1OUT       011000     RPn连接到比较器输出1
        C2OUT       011001     RPn连接到比较器输出2
        C3OUT       011010     RPn连接到比较器输出3
        U3TX        011011     RPn连接到UART3 发送
        U3RTS       011100     RPn连接到UART3 请求发送
        U4TX        011101     RPn连接到UART4 发送
        U4RTS       011110     RPn连接到UART4 请求发送
        SDO3        011111     RPn连接到SPI3 数据输出
        SCK3OUT     100000     RPn连接到SPI3 时钟输出
        SS3OUT      100001     RPn连接到SPI3 从选择
        SDO4        100010     RPn连接到SPI4 数据输出
        SCK4OUT     100011     RPn连接到SPI4 时钟输出
        SS4OUT      100100     RPn连接到SPI4 从选择
        OC9         100101     RPn连接到输出比较9 输出
        OC10        100110     RPn连接到输出比较10 输出
        OC11        100111     RPn连接到输出比较11 输出
        OC12        101000     RPn连接到输出比较12 输出
        OC13        101001     RPn连接到输出比较13 输出
        OC14        101010     RPn连接到输出比较14 输出
        OC15        101011     RPn连接到输出比较15 输出
        OC16        101100     RPn连接到输出比较16 输出
        PSYNCO1     101101     RPn连接到PWM 主时基同步输出
        PSYNCO2     101110     RPn连接到PWM 辅助时基同步输出
        QEI1CCMP    101111     RPn连接到QEI1 计数器比较器输出
        QEI2CCMP    110000     RPn连接到QEI2 计数器比较器输出
        REFCLK      110001     RPn连接到参考时钟输出
     ***************************************************************************/


const uint32_t SYSTEM_FOSC=80000000UL;

extern void SOFTWARE_RESET();
extern void GOTO_6000();
extern void GOTO_0000();

void PIN_MANAGER_Initialize(void);

void System_Delay_MS_g(uint32_t ms)
{
    uint32_t count=0,i,tip;
    tip = SYSTEM_FOSC/1000/30;
    for(i=0;i<ms;i++)
    {
        count=0;
        while(count<tip)
            count++;
    }
}
 
 inline static void INTERRUPT_GlobalEnable(void)
{
    __builtin_enable_interrupts();
}

/**
  @Summary
    Disables global interrupts of the dsPIC33EP256GP506

  @Description
    This routine disables the global interrupt bit for the dsPIC33EP256GP506

  @Preconditions
    None.

  @Returns
    None.

  @Param
    None.

  @Example
    <code>
    void SYSTEM_Initialize(void)
    {
        // Other initializers are called from this function
        INTERRUPT_GlobalDisable ();
    }
    </code>

*/
inline static void INTERRUPT_GlobalDisable(void)
{
    __builtin_disable_interrupts();
}

void System_Initialize_g(void)
{
    PIN_MANAGER_Initialize();
    
    /****************************
     * Fosc = Fin * (CLKDIVbits.PLLDIV+2)/(CLKDIVbits.PLLPRE+2)/(2*(CLKDIVbits.PLLPOST+1))
     * Fcp = Fosc/2
     ****************************/
    
    // FRCDIV FRC/1; PLLPRE 2; DOZE 1:8; PLLPOST 1:2; DOZEN disabled; ROI disabled; 
    CLKDIVbits.PLLPRE = 0; //PLL Phase Detector Input Divider Select,bit0:4  0000-2,0001-3,...,1111-33
    CLKDIVbits.PLLPOST = 0; //PLL VCO Output, bit6:7  00-2,01-4,10-reverse,11-8
    CLKDIVbits.FRCDIV = 1; //Internal Fast RC OScillator Postscaler bits,bit10:8,000-1,001-2,010-4,011-8,100-16,101-32,110-64,111-256
    CLKDIVbits.DOZEN = 0; //Dozen mode enable bit,bit11
    CLKDIVbits.DOZE = 3; //Processor Clock Reduction divided Select bits,Fcy divided,bit14:12,000-1,001-2,010-4,011-8,100-16,101-32,110-64,111-128
    CLKDIVbits.ROI = 0; //Recover on Intrrupt bit,0-no effect on dozen bit,bit15,1-Interrupts will clear the dozen bit and clock and peripheral clock radio set to 1:1
    
    // FRCDIV FRC/2; PLLPRE 2; DOZE 1:8; PLLPOST 1:2; DOZEN disabled; ROI disabled; 
    //CLKDIV = 0x3100;
    
    // FRC Oscillator Tuning bits, TUN Center frequency; 
    OSCTUN = 0x0;
    // ROON enabled; ROSEL disabled; RODIV Base clock value; ROSSLP disabled; 
    REFOCON = 0x8000;
    // PLLDIV 40=38+2; 
    PLLFBD = 38; //PLL Feedback Divisor bits, 000000000-2,...,111111111-513
    
    
    //PLLFrequency = 8000000 * (PLLFBD+2)/(CLKDIVbits.PLLPRE+2)/(2*(CLKDIVbits.PLLPOST+1));
    
    // RND disabled; SATB disabled; SATA disabled; ACCSAT disabled; 
	CORCONbits.RND = 0;
	CORCONbits.SATB = 0;
	CORCONbits.SATA = 0;
	CORCONbits.ACCSAT = 0;
    // CF no clock failure; NOSC PRIPLL; CLKLOCK unlocked; OSWEN Switch is Complete; 
    __builtin_write_OSCCONH((uint8_t) ((0x300 >> _OSCCON_NOSC_POSITION) & 0x00FF));
    __builtin_write_OSCCONL((uint8_t) ((0x300 | _OSCCON_OSWEN_MASK) & 0xFF));
    // Wait for Clock switch to occur
    while (OSCCONbits.OSWEN != 0);
}


void PIN_MANAGER_Initialize(void)
{
    TRISAbits.TRISA4 = 0;
    
    TRISCbits.TRISC0 = 0;  //LED_D3
    TRISCbits.TRISC1 = 0;  //LED_D4
    TRISCbits.TRISC7 = 1;  //ButtonS3
    
    TRISFbits.TRISF1 = 0; //CAN1TX-RF1
    TRISFbits.TRISF0 = 1; //CAN1RX-RF0
    
    TRISBbits.TRISB5 = 0; //UART2TX-RB5
    TRISBbits.TRISB6 = 1; //UART2RX-RB6
    
        
    TRISGbits.TRISG6 = 0;  //SCK2OUT-RG6
    TRISGbits.TRISG7 = 1;  //SDI2-RG7
    TRISGbits.TRISG8 = 0;  //SDO2-RG8
    TRISGbits.TRISG9 = 0;  //_CS2-RG9
    
    ANSELAbits.ANSA0 = 1; //RA0-AN0-ADC
    
    __builtin_write_OSCCONL(OSCCON & 0xbf); // unlock PPS
    
    
    RPOR0bits.RP20R = OutputRPnPpsToREFCLK;   //RA4->INTERNAL OSCILLATOR:REFCLK;
    
    RPINR0bits.INT1R = RP55_RC7;   //RC7->EXT_INT:INT1;

    RPOR7bits.RP97R = OutputRPnPpsToC1TX;   //RF1->ECAN1:C1TX;
    RPINR26bits.C1RXR = RPI96_RF0;   //RF0->ECAN1:C1RX;
    
    RPOR1bits.RP37R = OutputRPnPpsToU2TX;   //RB5->UART2:U2TX;
    RPINR19bits.U2RXR = RP38_RB6;   //RB6->UART2:U2RX;
    
    RPOR9bits.RP120R = 0x0008;   //RG8->SPI2:SDO2;
    RPINR22bits.SDI2R = 0x0077;   //RG7->SPI2:SDI2;
    RPOR8bits.RP118R = 0x0009;   //RG6->SPI2:SCK2OUT;

    __builtin_write_OSCCONL(OSCCON | 0x40); // lock   PPS
    
}


